import os
import pprint
from franticfallacy import engine
from franticfallacy.datafile import grammar

class Loader(object):
	target = None
	rules = None
	
	def __init__(self, object, ruleset):
		self.target = object
		self.rules = ruleset
		
	def takeResults(self, results):
		for entity in results:
			print '%s loading %s' % (self, entity)
		
			entattrs = entity.attrs.copy()
		
			type = entattrs.pop('_key',None)
			name = entattrs.pop('_value', [])[0]
			print type
			rule = self.rules.entTypes[type]
			obj = rule.targClass()
		
			store = getattr(self.target, self.rules.store[type])
			store[ name ] = obj
			if rule.named:
				setattr(obj, rule.named, name)
			
			loader = Loader(obj, rule)
			
			for a in entattrs:
				func = getattr(loader, rule.attrRules[a][0])
				func(entattrs[a], *rule.attrRules[a][1:])
		
			loader.takeResults(entity.children)
			
	def loadAttrCollection(self, value, attr, type):
		try:
			setattr( self.target, attr, type(value) )
		except TypeError:
			setattr( self.target, attr, type(value[0]) )
		
	def loadAttr(self, value, attr, type):
		setattr( self.target, attr, type(value[0]) )
		
	def addDictItem(self, item, attr):
		dict = getattr(self.target, attr)
		key = item[0]
		try:
			value = item[1]
		except IndexError:
			value = True
		dict.update({key: value})
		
	def __repr__(self):
		return '<Loader with target %s and rules %s>' % (self.target, self.rules)
				
class LoadRuleSet(object):
	targClass = None
	attrRules = {}
	entTypes = {}
	#store = {}
	named = False
	def __init__(self):
		self.store = {}
	
statusRules = LoadRuleSet()
statusRules.targClass = engine.Status
statusRules.attrRules = {
	'duration':('loadAttr','duration', str),
	'attrmult':('addDictItem','attrmult'),
	'attradd':('addDictItem','attradd'),
	'flag':('addDictItem','statusflags')
}
statusRules.named = 'name'

abilityRules = LoadRuleSet()
abilityRules.targClass = engine.Ability
abilityRules.attrRules = {
	'sortorder':('loadAttr','sortorder', int),
	'usable':('loadAttrCollection','usable', set),
	'target':('loadAttrCollection','targetmode', set),
	'mpcost':('loadAttr','mpcost', int),
	'attackattr':('loadAttr','attackattr', str),
	'attackpower':('loadAttr','attackpower', int),
	'attacktype':('loadAttr','attacktype', str),
	'usestring':('loadAttr','usestring', str),
	'defendattr':('loadAttr','defendattr', str),
	'attackflag':('addDictItem','attackflags')
}
abilityRules.entTypes['usestatus'] = statusRules
abilityRules.store['usestatus'] = 'usestatus'

worldFileRules = LoadRuleSet()
worldFileRules.entTypes['ability'] = abilityRules
worldFileRules.store['ability'] = 'abilities'

def loadWorld(dir):
	world = engine.World()
	
	#files = os.listdir(dir)
	files = ['core.ff']
	#print files
	for fn in files:
		try:
			print 'loading ' + fn + '...'
			f = open( os.path.join(dir, fn) )
			
			name = os.path.splitext(fn)[0]
			worldFile = engine.WorldFile(world, name)
			world.worldFiles[name] = worldFile
			
			loader = Loader(worldFile, worldFileRules)
			results = grammar.parse_file(f)
			
			loader.takeResults(results)
		except IOError:
			pass
			
	#now that all objects are loaded, go through and change all usestring 'spellcast' to preset message, ability names to references, etc
	
	return world


def loadWorldFile(worldfile, fileobj):
	worldstuff = grammar.parse_file(fileobj)
	pprint.pprint(worldstuff)
	for entity in worldstuff:
		print '\tloading %s...' % entity
		etype = entity['_key']
		name = entity['_value'][0]